package com.neusoft.spring;

import com.neusoft.service.AdminService;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.springframework.context.ApplicationContext;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ClassPathXmlApplicationContext implements BeanFactory {
    //创建一个map容器用于保存对象
    private Map<String,Object> beans = new HashMap<>();

    public ClassPathXmlApplicationContext() throws JDOMException, IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        //创建一个SAXBuilder对象
        SAXBuilder saxBuilder = new SAXBuilder();
        //解析XML文件
        Document document = saxBuilder.build(this.getClass().getClassLoader().getResourceAsStream("beans.xml"));
        //获取根元素
        Element root = document.getRootElement();
        //获取所有子元素
        List<Element> list = root.getChildren();
        for(int i = 0;i<list.size();i++) {
            Element element = list.get(i);  //从集合中获取到子节点
            String id = element.getAttributeValue("id");
            String clazz = element.getAttributeValue("class");
            //将clazz转换为对象
            Object o = Class.forName(clazz).newInstance(); //AdminServiceImpl
            //将获取到的id和clazz保存到Map容器中
            beans.put(id,o);
            //获取到bean中的property
            for(Element propertyElement:element.getChildren()){
                String name = propertyElement.getAttributeValue("name"); //adminDao
                String bean = propertyElement.getAttributeValue("bean"); // u
                //从Map容器中根据key获取到对象AdminDaoImpl
                Object beanObject = beans.get(bean); //AdminDaoImpl
                //通过反射动态调用public void setAdminDao(AdminDao adminDao)方法
                String methodName = "set" + name.substring(0,1).toUpperCase() + name.substring(1);
                Method method = o.getClass().getMethod(methodName,beanObject.getClass().getInterfaces()[0]); //获取方法名以及参数
                //调用方法
                method.invoke(o,beanObject);
            }
        }
    }

    @Override
    public Object getBean(String id) {
        return beans.get(id);
    }

    public static void main(String[] args) {
        try {
           BeanFactory beanFactory =  new ClassPathXmlApplicationContext();
//            ApplicationContext context = new org.springframework.context.support.ClassPathXmlApplicationContext();

           AdminService service = (AdminService) beanFactory.getBean("adminService"); //AdminServiceImpl
            service.getQueryById(100);
        } catch (JDOMException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

}



